/******************************************************************************
 *                     PIP : Parametric Integer Programming                   *
 ******************************************************************************
 *                                  maind.h                                   *
 ******************************************************************************
 *                                                                            *
 * Copyright Paul Feautrier, 1988-2005                                        *
 *                                                                            *
 * This library is free software; you can redistribute it and/or modify it    *
 * under the terms of the GNU Lesser General Public License as published by   *
 * the Free Software Foundation; either version 2.1 of the License, or (at    *
 * your option) any later version.                                            *
 *                                                                            *
 * This software is distributed in the hope that it will be useful, but       *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License   *
 * for more details.                                                          *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this library; if not, write to the Free Software Foundation,    *
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA         *
 *                                                                            *
 * Written by Paul Feautrier                                                  *
 *                                                                            *
 ******************************************************************************/

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>

#include "pip.h"
#include "version.h"

#ifdef UNIX
#include <sys/times.h>
#endif


/*extern long int cross_product ;*/
extern int verbose_xx ;
extern FILE * dump_xx ;
/*extern int compa_count;*/
extern int deepest_cut_xx;


#define balance_xx PIPLIB_NAME(balance)
void balance_xx(FILE *foo, FILE *bar)
{
 int level = 0;
 int c;
 while((c = dgetc_xx(foo)) != EOF)
     {
      switch(c)
	  {case '(' : level++; break;
	   case ')' : if(--level == 0) return;
	  }
      putc(c, bar);
     }
}

#define escape_xx PIPLIB_NAME(escape)
void escape_xx(FILE *foo, FILE *bar, int level)
{int c;
 while((c = dgetc_xx(foo)) != EOF)
   switch(c)
     {case '(' : level ++; break;
     case ')' : if(--level == 0)
		     { fprintf(bar, "\nSyntax error\n)\n");
		       return;
		     }
     }
}

int main(int argc, char *argv[])
{
 #ifdef UNIX
  struct tms chrono;
  int comptage = 1;
 #endif

 FILE *in, *out;
 Tableau_xx *ineq, *context, *ctxt;
 int nvar, nparm, ni, nc, bigparm;
 int nq; char * g;
 int simple = 0;
 struct high_water_mark_xx hq;
 int c, non_vide;
 int p, q, xq;
 piplib_int_t_xx x;
 piplib_int_init(x);
 #if defined(PIPLIB_ONE_DETERMINANT)
 #else
 piplib_int_t_xx i;
 #endif
 
 in = stdin; out = stdout;
 p = 1;
 if(argc > 1)
 { if(strcmp(argv[1], "-s") == 0)
	 { verbose_xx = -1;
	   p = 2;
	 }
   /* the number of 'v' in the verbose option control the amount of debug
    * information generated by Pip.
    */
   else
	 if(strncmp(argv[1], "-v", 2) == 0)
   { verbose_xx = 1;
     g = argv[1]+2;
     while(*g++ == 'v') verbose_xx++;
	  
     p = 2;
     dump_xx = pip_create_dump_file_xx();
     if (!dump_xx)
	verbose_xx = 0;
   }
   if(argc>p && strcmp(argv[p], "-d") == 0)
   { deepest_cut_xx = 1;
     p++;
   }
 }
	
 if(verbose_xx >= 0) fprintf(stderr, "Version "PIPLIB_HEAD"\n");
 if(argc > p)
 { if(strcmp(argv[p], "-z") == 0)
   { simple = 1;
     p++;
   }
   
	 in = fopen(argv[p], "r");
   if(in == NULL)
   { fprintf(stderr, "%s unaccessible\n", argv[p]);
     exit(1);
   }
 }
 p++;
 if(argc>p)
 { out = fopen(argv[p], "w");
   if(out == NULL)
   { fprintf(stderr, "%s unaccessible\n", argv[p]);
     exit(2);
   }
 }
 
 p++;
 sol_init_xx();
 tab_init_xx();
 while((c = dgetc_xx(in)) != EOF)
     {if(c != '(') continue;
      fprintf(out, "(");
      balance_xx(in, out);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else 
        nvar = piplib_int_get_si(x);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else
        nparm = piplib_int_get_si(x);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else 
        ni = piplib_int_get_si(x);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else
        nc = piplib_int_get_si(x);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else 
        bigparm = piplib_int_get_si(x);
      if(dscanf_xx(in, &x) < 0) {
        escape_xx(in, out, 1); continue;
      } else 
        nq = piplib_int_get_si(x);
      
      if(verbose_xx > 0) {
        fprintf(dump_xx, "%d %d %d %d %d %d\n",
                                    nvar, nparm, ni, nc, bigparm, nq);
        fflush(dump_xx);
      }
      /*cross_product = 0;*/
      hq = tab_hwm_xx();
      if(verbose_xx > 0) {fprintf(dump_xx, "hwm %p\n", g);
                       fflush(dump_xx);
                      }
      ineq = tab_get_xx(in, ni, nvar+nparm+1, nvar);
      if (nq)
	  tab_simplify_xx(ineq, nvar);
      if(ineq == NULL){escape_xx(in, out, 2); continue;}
      context = tab_get_xx(in, nc, nparm+1, 0);
      if (nq)
	  tab_simplify_xx(context, nparm);
      if(context == NULL){escape_xx(in, out, 2); continue;}
      xq = p = sol_hwm_xx();
/* verification de la non-vacuite' du contexte */
      if(nc)
      {ctxt = expanser_xx(context, nparm, nc, nparm+1, nparm, 0, 0);
       traiter_xx(ctxt, NULL, nparm, 0, nc, 0, -1, TRAITER_INT);
       non_vide = is_not_Nil_xx(p);
       sol_reset_xx(p);
      }
      else non_vide = Pip_True;
      if(non_vide) {
       /*compa_count = 0;*/
       traiter_xx(
         ineq, context, nvar, nparm, ni, nc, bigparm, nq ? TRAITER_INT : 0);
	if (verbose_xx > 0) {
	    fprintf(dump_xx, "det: ");
#if defined(PIPLIB_ONE_DETERMINANT)
	    piplib_int_print(dump_xx, ineq->determinant);
#else
	    for (i=0; i<ineq->l_determinant; i++) {
		fprintf(dump_xx, piplib_int_format, ineq->determinant[i]);
		fprintf(dump_xx, " ");
	    }
#endif
	    fprintf(dump_xx, "\n");
	}
	fputs(")\n",out);
       if(simple) sol_simplify_xx(xq);
       q = sol_hwm_xx();
       while((xq = sol_edit_xx(out, xq)) != q);
       sol_reset_xx(p);
      }
      else fprintf(out, "void\n");
      tab_reset_xx(hq);
      if(verbose_xx > 0) fflush(dump_xx);
      /* add a right parenthesis in order to keep the output in balance */
      fprintf(out, ")\n");
      fflush(out);
      if(verbose_xx >= 0) 
       fprintf(stderr,"cross : (%ld), compa : (%d)\n\r",
               /*cross_product*/0L, /*compa_count*/0);
      #ifdef UNIX
       comptage++;
      #endif
     }
#ifdef UNIX
 times(& chrono);
 fprintf(stderr, "n %d u %d''' s %d'''\r\n",
 comptage, chrono.tms_utime, chrono.tms_stime);
#endif

 piplib_int_clear(x);
 pip_close_xx();
 return 0;
}

